package com.wjk.kylin.rpc.core.provider.impl;

import com.wjk.kylin.rpc.core.provider.RpcProviderFactory;
import com.wjk.kylin.rpc.core.provider.annotation.RpcService;
import com.wjk.kylin.rpc.core.util.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * kylin-rpc provider (for spring)
 * @author wjk
 */
public class RpcSpringProviderFactory extends RpcProviderFactory implements ApplicationContextAware, InitializingBean, DisposableBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(RpcSpringProviderFactory.class);

    /**
     * ApplicationContextAware 接口 方法
     * spring 启动 拿到使用RpcService的所有的bean 对象
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> serviceBeanMap = applicationContext.getBeansWithAnnotation(RpcService.class);
        if (!CollectionUtils.isEmpty(serviceBeanMap)) {
            for (Object serviceBean : serviceBeanMap.values()) {
                // valid 使用RpcService注解的类 必须实现接口
                if (serviceBean.getClass().getInterfaces().length == 0) {
                    throw new RpcException("kylin-rpc, service(RpcService) must inherit interface.");
                }
                // add service
                RpcService rpcService = serviceBean.getClass().getAnnotation(RpcService.class);

                //获取接口全名称
                String interfaceName = serviceBean.getClass().getInterfaces()[0].getName();
                String version = rpcService.version();

                //调用父类方法 注册接口 对象
                super.addService(interfaceName, version, serviceBean);
            }
        }
    }

    /**
     * 这个方法将在所有的属性被初始化后调用
     * 先执行  setApplicationContext -> setApplicationContext
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        LOGGER.info(">>>>>>>>>>> kylin-rpc provider factory start");

        super.start();
    }

    /**
     * 销毁时调用
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        LOGGER.info(">>>>>>>>>>> kylin-rpc provider factory destroy");

        super.stop();
    }

}
